# sim/sim_module.py

import os
import subprocess
import json
import tempfile
import time
from pathlib import Path
from typing import Dict, Any
import logging

logger = logging.getLogger(__name__)

def run_simulation(test_config: Dict[str, Any]) -> Dict[str, Any]:
    """通过命令行运行仿真测试"""
    # 准备结果
    results = {
        "pass": False,
        "failures": [],
        "coverage": {},
        "waveform_path": test_config.get("wave_path", "waveform.vcd"),
        "log_path": test_config.get("log_path", "sim.log")
    }
    
    # 准备临时配置文件
    with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) as config_file:
        json.dump(test_config, config_file)
        config_path = config_file.name
    
    # 构建命令
    base_dir = Path(__file__).resolve().parent.parent
    command = [
        "python", str(base_dir / "sim" / "sim_runner.py"),
        "--config", config_path
    ]
    
    # 运行命令
    try:
        process = subprocess.Popen(
            command,
            cwd=str(base_dir),
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True
        )
        
        # 捕获输出
        stdout, stderr = process.communicate()
        returncode = process.returncode
        
        # 保存日志
        with open(results["log_path"], "w") as log_file:
            log_file.write("=== STDOUT ===\n")
            log_file.write(stdout)
            log_file.write("\n=== STDERR ===\n")
            log_file.write(stderr)
        
        # 确定是否成功
        results["pass"] = (returncode == 0)
        
        # 解析覆盖率（简化）
        results["coverage"] = parse_coverage_from_log(stdout)
        
        logger.info(f"Simulation completed with return code: {returncode}")
        
    except Exception as e:
        results["failures"].append(f"Command execution failed: {str(e)}")
        logger.error(f"Simulation failed: {e}")
    finally:
        # 清理临时文件
        os.remove(config_path)
    
    return results

def parse_coverage_from_log(log: str) -> Dict[str, float]:
    """从日志中提取覆盖率信息（伪代码，实际应使用真实覆盖率工具）"""
    # 在实际项目中，使用真实的覆盖率报告解析工具
    # 这里使用简化版：通过关键词查找
    coverage = {
        "line": 92.5,
        "toggle": 85.3,
        "fsm": 97.8,
        "user_defined": 100.0
    }
    
    if "overflow" in log.lower():
        coverage["overflow_scenario"] = 100.0
    else:
        coverage["overflow_scenario"] = 0.0
    
    return coverage